package jmine.tec.batch.services;

import jmine.tec.batch.JmineTecBatchMessages;
import jmine.tec.batch.domain.MProcess;
import jmine.tec.di.annotation.Injected;
import jmine.tec.services.annotations.Execution;
import jmine.tec.services.annotations.Input;
import jmine.tec.services.annotations.ServiceImplementor;
import jmine.tec.services.api.ActionsEnum;
import jmine.tec.services.api.RawInput;
import jmine.tec.services.api.ServiceExecutionException;
import jmine.tec.services.api.export.ReferenceMap;
import jmine.tec.services.api.export.ServiceFiller;
import jmine.tec.services.io.ServiceBean;
import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.persist.dao.BeanNotFoundException;

/**
 * Servico de inclusão de {@link MProcess}.
 * 
 * @author Rafael Volpato
 * @date Oct 30, 2009
 */
@ServiceImplementor(action = ActionsEnum.INCLUIR)
public class MProcessService implements ServiceFiller<MProcess> {

    private static final String MNEMONICO = "Mnemonico";

    private static final String DESCRICAO = "Descrição";

    private static final String CLASS_NAME = "Classe";

    private static final String DATABASE_ID = "Database ID";

    private static final String SERVICE_NAME = "MProcess";

    // parameters
    private String mnemonico;

    private String descricao;

    private Long databaseID;

    // injected
    private BaseDAO<MProcess> dao;

    private RawInput rawInput;

    /**
     * @param dao the dao to set
     */
    @Injected
    public void setDao(BaseDAO<MProcess> dao) {
        this.dao = dao;
    }

    /**
     * @param rawInput the serviceProperties to set
     */
    @Injected
    public void setRawInput(RawInput rawInput) {
        this.rawInput = rawInput;
    }

    /**
     * @param mnemonico the mnemonico to set
     */
    @Input(fieldName = MNEMONICO)
    public void setMnemonico(String mnemonico) {
        this.mnemonico = mnemonico;
    }

    /**
     * @param descricao the descricao to set
     */
    @Input(fieldName = DESCRICAO, required = false)
    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    /**
     * @param databaseID the databaseID to set
     */
    @Input(fieldName = DATABASE_ID, required = false)
    public void setDatabaseID(Long databaseID) {
        this.databaseID = databaseID;
    }

    /**
     * Executa a inclusão de um novo {@link MProcess}.
     * 
     * @throws ServiceExecutionException se ja existir um {@link MProcess} com o mnemonico informado
     */
    @SuppressWarnings("deprecation")
    @Execution
    public void execute() throws ServiceExecutionException {
        try {
            this.dao.findByNaturalKey(this.mnemonico);

            // Ja existe um mprocess com o mnemonico informado, lançar erro
            throw new ServiceExecutionException(JmineTecBatchMessages.SERVICES_MPROCESS_ALREADY_EXISTS.create(this.mnemonico));
        } catch (BeanNotFoundException e) {
            // Se não existe um mprocess com o mnemonico informado, cadastrar um novo.
        }

        MProcess mprocess = this.dao.createBean();
        mprocess.setMnemonico(this.mnemonico);
        mprocess.setDescr(this.descricao);
        mprocess.setClassName(this.rawInput.getRaw(CLASS_NAME));

        if (this.databaseID != null) {
            mprocess.getController().getSessionFactory().getCurrentSession().save(mprocess, this.databaseID);
        }

        mprocess.getPersister().save();
    }

    /**
     * {@inheritDoc}
     */
    public void fillServiceBean(ServiceBean bean, ReferenceMap referenceMap, MProcess entity) {
        bean.setAction(ActionsEnum.INCLUIR);
        bean.setName(SERVICE_NAME);

        bean.putParameter(MNEMONICO, entity.getMnemonico());
        bean.putParameter(DESCRICAO, entity.getDescr());
        bean.putParameter(CLASS_NAME, entity.getClassName());
        bean.putParameter(DATABASE_ID, entity.getId().toString());
    }
}
